home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Aminet 15
/
Aminet 15 - Nov 1996.iso
/
Aminet
/
comm
/
mail
/
YamNet.lha
/
FSCode.lha
/
Src
/
FSCode.c
< prev
next >
Wrap
C/C++ Source or Header
|
1995-11-13
|
6KB
|
253 lines
/*
** $VER: FSCode.c (22.5.95) by Flavio Stanchina
** Loc. Montevaccino, 39
** 38040 Trento (Italy)
** 2:333/408.9@fidonet.org
*/
#include <exec/types.h>
#include <exec/alerts.h>
#include <exec/memory.h>
#include <dos/dos.h>
#include <dos/dosasl.h>
#include <dos/dosextens.h>
#include <dos/rdargs.h>
#include <dos/stdio.h>
#include <clib/exec_protos.h>
#include <clib/utility_protos.h>
#include <clib/dos_protos.h>
#include <ctype.h>
#include <string.h>
#if defined(__SASC)
#define _USEOLDEXEC_
#include <proto/exec.h>
#include <proto/utility.h>
#include <proto/dos.h>
#endif
#include "FSCode.h"
#include "FSCode_rev.h"
#include "CRC32.h"
/***** Strings *****/
TEXT StartFmt[] = "!start %s\n";
TEXT MultiFmt[] = "!mstrt %ld/%ld %s\n";
TEXT EndFmt[] = "!end %ld %lx\n\n";
TEXT NameFmt[] = "%s%ld";
TEXT Template[] = "FILE/A,TO,E=ENCODE/S,M=MULTI/S,L=LINES/N" VERSTAG " by Flavio Stanchina";
LONG FSCode(VOID)
{
struct RDArgs *rda;
struct FSData *fsd;
struct Process *pr;
ULONG tmp;
if (fsd = AllocMem(sizeof(struct FSData), MEMF_CLEAR))
{
/* Open libraries (and make sure we're on OS 2.04 or greater) */
if ((DOSBase = (struct DosLibrary *)OpenLibrary("dos.library", 37)) == NULL)
{
Alert(AT_Recovery | AG_OpenLib | AO_DOSLib);
return RETURN_FAIL + 0;
}
if ((UtilityBase = OpenLibrary("utility.library", 37)) == NULL)
{
Alert(AT_Recovery | AG_OpenLib | AO_UtilityLib);
return RETURN_FAIL + 1;
}
pr = (struct Process *)FindTask(NULL);
if (pr->pr_CES == 0)
{
struct CommandLineInterface *cli = Cli();
if (cli && cli->cli_StandardOutput)
fsd->StdErr = cli->cli_StandardOutput;
else fsd->StdErr = pr->pr_COS;
}
else fsd->StdErr = pr->pr_CES;
if (rda = ReadArgs(Template, (LONG *)fsd, NULL))
{
/* Set up CRC table */
CRC32_init();
/* Encode or decode? */
if (fsd->Encode)
{
if (fsd->In = Open(fsd->File, MODE_OLDFILE))
{
if ((fsd->RealSize = FileSizeFH(fsd, fsd->In)) > 0)
{
if (fsd->Multi)
{
fsd->Lines = 100;
if (fsd->pLines)
{
if (*fsd->pLines < 2)
FPuts(fsd->StdErr, "too few LINES -- using default value\n");
else fsd->Lines = *fsd->pLines;
}
// fsd->Parts = (((fsd->RealSize - 1) / 60) + fsd->Lines - 1) / fsd->Lines;
tmp = UDivMod32(fsd->RealSize - 1, 60);
fsd->Parts = UDivMod32(tmp + fsd->Lines - 1, fsd->Lines);
if (fsd->Parts <= 1) fsd->Multi = 0; // easier
}
switch (Encode(fsd))
{
case -3:
MyPrintFault(fsd, ERROR_BREAK, NULL);
break;
}
}
else FPrintf(fsd->StdErr, "file \"%s\" is empty\n", fsd->File);
MyClose(fsd, fsd->In);
}
else MyPrintFault(fsd, IoErr(), fsd->File);
}
else
{
if (fsd->pLines)
FPuts(fsd->StdErr, "LINES is meaningless in decode mode -- ignored\n");
if (OpenPart(fsd))
{
switch(Decode(fsd))
{
case '!':
FPuts(fsd->StdErr, "illegal '!' -- file corrupt\n");
break;
case -1:
FPuts(fsd->StdErr, "unexpected EOF\n");
break;
case -2:
MyPrintFault(fsd, IoErr(), fsd->To);
break;
case -3:
MyPrintFault(fsd, ERROR_BREAK, NULL);
break;
}
ClosePart(fsd, 0); // flush the output file
// NOTE: This is meaningful only in case of errors, 'cause if
// all went ok the file has already been closed when the !end
// line has been encountered.
}
/* Did we decode anything at all? */
if (fsd->NumFound == 0)
FPuts(fsd->StdErr, "no start line\n");
/* Make sure files are closed. Should hit these only in case of errors. */
if (fsd->In ) MyClose(fsd, fsd->In );
if (fsd->Out) MyClose(fsd, fsd->Out);
}
free:
FreeArgs(rda);
}
else MyPrintFault(fsd, IoErr(), NULL);
CloseLibrary((struct Library *)DOSBase);
CloseLibrary((struct Library *)UtilityBase);
FreeMem(fsd, sizeof(struct FSData));
}
else Alert(AT_Recovery | AG_NoMemory);
return RETURN_OK;
}
/***** Restituisce la lunghezza di un file già aperto *****/
LONG FileSizeFH(struct FSData *fsd, BPTR fh)
{
struct FileInfoBlock *fib;
LONG size = -1;
if (fib = AllocDosObject(DOS_FIB, NULL))
{
if (ExamineFH(fh, fib))
size = fib->fib_Size;
FreeDosObject(DOS_FIB, fib);
}
return size;
}
/***** Print fault on given file *****/
VOID MyPrintFault(struct FSData *fsd, LONG code, STRPTR header)
{
static TEXT buffer[256];
Fault(code, header, buffer, 256);
FPrintf(fsd->StdErr, "\a%s\n", buffer);
Flush(fsd->StdErr);
}
/***** Close file and check for errors *****/
BOOL MyClose(struct FSData *fsd, BPTR fh)
{
BOOL rc;
if ((rc = Close(fh)) == 0)
MyPrintFault(fsd, IoErr(), "error closing file");
return rc;
}
/***** Get a decimal number from a string *****/
LONG GetDec(STRPTR *line)
{
LONG l = 0;
while (!isdigit(*(*line))) (*line)++;
while ( isdigit(*(*line))) l = (l * 10) + (*(*line)++ - '0');
return l;
}
/***** Get a hexadecimal number from a string *****/
static LONG h2l(LONG c)
{
if (c >= 'a') return c - 'a' + 10; // 'f' > 'F'
if (c >= 'A') return c - 'A' + 10; // 'F' < 'f'
return c - '0';
}
LONG GetHex(STRPTR *line)
{
LONG l = 0;
while (!isxdigit(*(*line))) (*line)++;
while ( isxdigit(*(*line))) l = (l * 16) + h2l(*(*line)++);
return l;
}
/***** Remove leading spaces and trailing control characters *****/
VOID TrimLine(STRPTR *line)
{
register i;
while (isspace(*(*line))) (*line)++;
for (i = 0; (*line)[i] & 0x60; i++);
(*line)[i] = '\0';
}
VOID SPrintf(STRPTR buf, STRPTR fmt, ...)
{
RawDoFmt(fmt, (APTR)(&fmt + 1), stuff, buf);
}
/***** EOF *****/